﻿#region Copyright(C) 2018 FI Ltd. All rights reserved.
// ==================================================================================================
// Copyright(C) 2018 FI Ltd. All rights reserved.
//
// SYSTEM NAME      : FI.Net Application Framework
// COMPONENT ID     : ApplicationContext
// COMPONENT DESC   : Session based contextual data sharing.
//
// CREATED DATE/BY  : 18 Aug 2018 / Tian Mi
//
// REVISION HISTORY :
// DATE/BY            SR#/CS/PM#/OTHERS      DESCRIPTION OF CHANGE
// ==================================================================================================
#endregion

using FI.Core.Configuration;
using FI.Core.IoC;
using FI.Core.Utilities;
using System.ComponentModel;
using System.Configuration;

namespace FI.Core.ApplicationContexts.Configuration
{
    /// <summary>
    /// Define the application context setting.
    /// </summary>
    [ConfigurationSectionName(Constants.ConfigurationSections.ApplicationContexts)]
    public class ApplicationContextSettings :ServiceLocatableSettings
    {
        #region Constants
        private const string ContextLocatorsProperty            = "contextLocators";
        private const string DefaultContextLocatorNameProperty  = "defaultContextLocator";
        private const string ContextAttachBehaviorProperty      = "contextAttachBehavior";
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the context attach behavior.
        /// </summary>
        /// <value>The context attach behavior.</value>
        [ConfigurationProperty(ContextAttachBehaviorProperty, IsRequired = false, DefaultValue = ContextAttachBehavior.Clear)]
        public ContextAttachBehavior ContextAttachBehavior
        {
            get { return (ContextAttachBehavior)this[ContextAttachBehaviorProperty]; }
            set { this[ContextAttachBehaviorProperty] = value; }
        }

        /// <summary>
        /// Gets the collection of defined ContextLocator objects.
        /// </summary>
        /// <value>
        /// The collection of defined ContextLocator objects.
        /// </value>
        [ConfigurationProperty(ContextLocatorsProperty, IsRequired = true)]
        public NameTypeConfigurationElementCollection<ContextLocatorDataBase> ContextLocators
        {
            get { return (NameTypeConfigurationElementCollection<ContextLocatorDataBase>)this[ContextLocatorsProperty]; }
            set { this[ContextLocatorsProperty] = value; }
        }

        /// <summary>
        /// Gets or sets the default service locator.
        /// </summary>
        /// <value>The default service locator.</value>
        [ConfigurationProperty(DefaultContextLocatorNameProperty, IsRequired = true)]
        public string DefaultContextLocator
        {
            get{ return this[DefaultContextLocatorNameProperty] as string; }
            set { this[DefaultContextLocatorNameProperty] = value; }
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Configures the specified service locator.
        /// </summary>
        /// <param name="serviceLocator">The service locator.</param>
        public override void Configure(IServiceLocator serviceLocator)
        {
            Guard.ArgumentNotNull(serviceLocator, "serviceLocator");
            foreach (ContextLocatorDataBase contextLocatorData in this.ContextLocators)
            {
                var creator = contextLocatorData.GetProviderCreator(this);
                if (null != creator)
                {
                    serviceLocator.Register<ContextLocatorBase>(creator, contextLocatorData.Name, contextLocatorData.Name == this.DefaultContextLocator, contextLocatorData.Lifetime);
                }
            }
        }
        #endregion
    }
}